<?php
/**
 * User: 呆呆
 * Agreement: 禁止使用本软件（系统）用于任何违法违规业务或项目,造成的任何法律后果允由使用者（或运营者）承担
 * Date: 2021/3/3
 * Time: 14:34
 */
namespace app\index\controller;
use think\Db;
use think\Controller;
use app\wenjian\QrcodeServer;

class Pay extends Controller
{
    public function getReturn($code = 1, $msg = "成功", $data = null)
    {
        return array("code" => $code, "msg" => $msg, "data" => $data);
    }
    
    public function index()//发起创建订单
    {
        $data = Db::name("pay_sz")->find();
        if($data['ds_hfw']==2){
            $this->success('网站正在升级维护中....',null,$data['ds_outr']);
        }else{
        error_reporting(0);    
        $api = input();
        if(!$api){
            $this->redirect(http_type());
        }
        
        closeEndOrder();//检测过期订单
        
        $pid = $api['pid'];
        if (!$pid || $pid == "") {
            $this->success('1001',null,'pid（附加信息：商户PID（商户后台获取）参数错误');
        }
        $dsa = Db::name("pay_user")->where("id",$pid)->find();
        if(!$dsa || $dsa['active']==1 and $dsa['type']!=2){
            $this->success('1001',null,'pid（附加信息：您使用的商户PID已被禁用或者不存在，请联系客服咨询原因');
        }
        
        $orderId = date("YmdHms").rand(1, 9).rand(1, 9).rand(1, 9).rand(1, 9);//云端订单号
        if($dsa['duijei']==1){//对接模式
            $orderId = $this->mrpay($api,$orderId);//默认叁数
        }else{
            $orderId = $this->yzfpay($api,$orderId);//易支付叁数
        }
        
        $ta = Db::name("pay_sz")->find();
        if(isMobile() and $ta['ds_zhto']==1){
            if(is_weixin()){
                $data['order_id'] = http_type().url('pay/pay').'?orderid='.$orderId;//跳转的地址
                $this->assign('data',$data);
                return $this->fetch('pay/vxqqzfb');//支付页面||微信内
            }else{
                return redirect(http_type().url('pay/pay').'?orderid='.$orderId);//支付页面||微信外
            }
        }else{
            return redirect(http_type().url('pay/pay').'?orderid='.$orderId);//支付页面||电脑版
        }
          
        }
    }
    
    public function yzfpay($api,$orderId)//易支付叁数
    {
        $pid = $api['pid'];
        if (!$pid || $pid == "") {
            $this->success('1001',null,'pid（附加信息：商户PID（商户后台获取）参数错误');
        }
        $type = $api['type'];
        if (!$type || $type == "") {
            $this->success('1002',null,'type（附加信息：支付方式（商户后台获取）参数错误');
        }
        $out_trade_no = $api['out_trade_no'];
        if (!$out_trade_no || $out_trade_no == "") {
            $this->success('1003',null,'out_trade_no（附加信息：网站的订单号或用户名）参数错误');
        }
        $money = $api['money'];
        if (!$money || $money == "") {
            $this->success('1004',null,'money（金额）参数错误');
        }
        if($money<=0 || !is_numeric($money) || !preg_match('/^[0-9.]+$/', $money)) {
            $this->success('1007',null,'money（附加信息：金额不合法）');
        }
        $return_url = $api['return_url'];
        if (!$return_url || $return_url == "") {
            $this->success('1005',null,'return_url（附加信息：当支付成功或支付超时后将自动跳转到指定网址）参数错误');
        }
        $notify_url = $api['notify_url'];
        if (!$notify_url || $notify_url == "") {
            $this->success('1006',null,'notify_url（附加信息：当支付成功回调数据逻辑来编写您的业务）参数错误');
        }
        $name = $api['name'];
        if (!$name || $name == "") {
            $this->success('1007',null,'name（附加信息：商品名称）参数错误');
        }
        $sign = $api['sign'];
        if (!$sign || $sign == "") {
            $this->success('1008',null,'sign（附加信息：数据签名（签名方法商户后台获取）参数错误');
        }
        $dsa = Db::name("pay_user")->where("id",$pid)->find();
        $key = jfjf($api,$sign,$dsa['key']);//数据签名算法
        if(!$key){
             $this->success('1009',null,'sign（附加信息：数据签名（签名方法商户后台获取）签名错误');
        }
        $fti = Db::name("pay_order")->where("pid", $pid)->where("record", $out_trade_no)->find();//判断商户订单号已存在
        if($fti){
          $this->success('1010',null,'out_trade_no（附加信息：商户订单号已存在）请重新唤起支付');
        }
        if($type=='alipay'){
            $type = 'alipay';
        }elseif($type=='wxpay'){
            $type = 'weixin';
        }elseif($type=='qqpay'){
            $type = 'qq';
        }
        $sxf = money($money,$dsa);//手续费算法
        if($sxf>$dsa['money']){
          $this->success('1010',null,'当前商户余额不足，无法完成支付，请商户登录用户中心充值余额');
        }
        $mid = $api['mid'];
        if (!$mid || $mid == "") {
            $data = $this->land($pid,$type);//随机账号
            $price = $this->mqf($pid,$data,$money,$type,$orderId);//获取金额判断
            $run = $this->tongtao($data,$price,$type);//获取通道支付信息
        }else{
            $data = Db::name("pay_gfg")->where("pid", $pid)->where("mid", $mid)->where("land_lx", 1)->where("state", 1)->find();//指定账号
            if(!$data){
                $this->success('1015',null,'暂无账户可用,请稍后再试');
            }
            $data = $this->rzjr($data);//账号限额配置
            $data = $this->ds($data);//账号限量配置
            $jie = Db::name("pay_jie")->where("pid", $data['pid'])->where("id", $data['typec_id'])->where("state", 1)->find();//获取通道
            if(!$jie){
                $this->bug($data,'该通道已关闭');//账号异常配置
                $this->success('1013',null,'订单创建失败（错误信息：该通道已关闭)');
            }
            $price = $this->mqf($pid,$data,$money,$type,$orderId);//获取金额判断
            $cls = app("\\app\common\controller\\".$jie['game_dm']);//支付通道路径
            $run = $cls->exec($data,$price,$type);//支付通道数据
            if($run['code']==-1){
                $this->bug($data,$run['data']);//账号异常配置
                $this->success('1014',null,'订单创建失败（错误信息：'.$run['data'].')');
            }
        }
        $jie = Db::name("pay_jie")->where("pid", $data['pid'])->where("id", $data['typec_id'])->where("state", 1)->find();//获取通道
        if($data['jkstate']==0){
            $this->success('1017',null,'监控状态异常，请检查是否挂监控回调');
        }
        $data = array(
            "pid" => $pid,//商户PID
            "order_id" => $orderId,//云端订单号
            "pay_id" => $run['data']['pay_id'],//通道订单号
            "record" => $out_trade_no,//商户订单号
            "type" => $type,//支付方式
            "name" => $name,//商品名称
            "sitename" => $sitename = ($api['sitename']==''? '无数据':$api['sitename']),//网站名称
            "refer" => $return_url,//同步回调
            "notify" => $notify_url,//异步回调
            "money" => $money,//金额
            "price" => $price,//实际金额
            "sxf" => $sxf,//手续费
            "mid" => $data['mid'],//收款账号MID
            "mid_id" => $data['typec_id'],//通道ID
            "mid_name" => $data['username'],//收款账号
            "mid_dm" => $jie['game_dm'],//通道标识
            "mid_type" => $data['typec_name'],//所属通道
            "mid_url" => $run['data']['mid_url'],//通道二维码
            "mid_json" => ($run['json']==''? '无数据':$run['json']),//通道数据
            "ip" => real_ip(),//交易IP
            "create_date" => time(),//创建时间戳（10位）
        );
        Db::name("pay_order")->insert($data);
        
        return $orderId;
        
    }
    
    public function mrpay($api,$orderId)//默认叁数
    {
        $pid = $api['pid'];
        if (!$pid || $pid == "") {
            $this->success('1001',null,'pid（附加信息：商户PID（商户后台获取）参数错误');
        }
        $type = $api['type'];
        if (!$type || $type == "") {
            $this->success('1002',null,'type（附加信息：支付方式（商户后台获取）参数错误');
        }
        $record = $api['record'];
        if (!$record || $record == "") {
            $this->success('1003',null,'record（附加信息：网站的订单号或用户名）参数错误');
        }
        $money = $api['money'];
        if (!$money || $money == "") {
            $this->success('1004',null,'money（金额）参数错误');
        }
        if($money<=0 || !is_numeric($money) || !preg_match('/^[0-9.]+$/', $money)) {
            $this->success('1007',null,'money（附加信息：金额不合法）');
        }
        $refer = $api['refer'];
        if (!$refer || $refer == "") {
            $this->success('1005',null,'refer（附加信息：当支付成功或支付超时后将自动跳转到指定网址）参数错误');
        }
        $notify = $api['notify'];
        if (!$notify || $notify == "") {
            $this->success('1006',null,'notify（附加信息：当支付成功回调数据逻辑来编写您的业务）参数错误');
        }
        $sign = $api['sign'];
        if (!$sign || $sign == "") {
            $this->success('1008',null,'sign（附加信息：数据签名（签名方法商户后台获取）参数错误');
        }
        $dsa = Db::name("pay_user")->where("id",$pid)->find();
        $key = sign($api,$dsa['key']);//数据签名算法
        if($sign!==$key){
             $this->success('1009',null,'sign（附加信息：数据签名（签名方法商户后台获取）签名错误');
        } 
        $sxf = money($money,$dsa);//手续费算法
        if($sxf>$dsa['money']){
          $this->success('1010',null,'当前商户余额不足，无法完成支付，请商户登录用户中心充值余额');
        }
        $mid = $api['mid'];
        if (!$mid || $mid == "") {
            $data = $this->land($pid,$type);//随机账号
            $price = $this->mqf($pid,$data,$money,$type,$orderId);//获取金额判断
            $run = $this->tongtao($data,$price,$type);//获取通道支付信息
        }else{
            $data = Db::name("pay_gfg")->where("pid", $pid)->where("mid", $mid)->where("land_lx", 1)->where("state", 1)->find();//指定账号
            if(!$data){
                $this->success('1015',null,'暂无账户可用,请稍后再试');
            }
            $data = $this->rzjr($data);//账号限额配置
            $data = $this->ds($data);//账号限量配置
            $jie = Db::name("pay_jie")->where("pid", $data['pid'])->where("id", $data['typec_id'])->where("state", 1)->find();//获取通道
            if(!$jie){
                $this->bug($data,'该通道已关闭');//账号异常配置
                $this->success('1013',null,'订单创建失败（错误信息：该通道已关闭)');
            }
            $price = $this->mqf($pid,$data,$money,$type,$orderId);//获取金额判断
            $cls = app("\\app\common\controller\\".$jie['game_dm']);//支付通道路径
            $run = $cls->exec($data,$price,$type);//支付通道数据
            if($run['code']==-1){
                $this->bug($data,$run['data']);//账号异常配置
                $this->success('1014',null,'订单创建失败（错误信息：'.$run['data'].')');
            }
        }
        $jie = Db::name("pay_jie")->where("pid", $data['pid'])->where("id", $data['typec_id'])->where("state", 1)->find();//获取通道
        if($data['jkstate']==0){
            $this->success('1017',null,'监控状态异常，请检查是否挂监控回调');
        }
        $data = array(
            "pid" => $pid,//商户PID
            "order_id" => $orderId,//云端订单号
            "pay_id" => $run['data']['pay_id'],//通道订单号
            "record" => $record,//附加参数
            "type" => $type,//支付方式
            "name" => $record,//商品名称
            "money" => $money,//金额
            "price" => $price,//实际金额
            "sxf" => $sxf,//手续费
            "refer" => $refer,//同步回调
            "notify" => $notify,//异步回调
            "mid" => $data['mid'],//收款账号MID
            "mid_id" => $data['typec_id'],//通道ID
            "mid_name" => $data['username'],//收款账号
            "mid_dm" => $jie['game_dm'],//通道标识
            "mid_type" => $data['typec_name'],//所属通道
            "mid_url" => $run['data']['mid_url'],//通道二维码
            "mid_json" => ($run['json']==''? '无数据':$run['json']),//通道数据
            "ip" => real_ip(),//交易IP
            "create_date" => time(),//创建时间戳（10位）
        );
        Db::name("pay_order")->insert($data);
        
        return $orderId;
        
    }
    
    public function land($pid,$type)//随机账号轮询
    {
        if($type=='alipay'){
            $type = '1';
        }elseif($type=='weixin'){
            $type = '0';
        }elseif($type=='qq'){
            $type = '2';
        }
        $cou = Db::name("pay_gfg")->where("pid", $pid)->where("type", $type)->where("jkstate", 1)->where("state", 1)->where("land_lx", 1)->where("ds_status", 0)->find();
        if($cou==false){
            $this->success('1009',null,'暂无账户可用,请稍后再试');
        }
        $table = "pay_gfg";    //需要抽取的数据表
        $pk = Db::name("$table")->getPK();//获取主键
        $countcus = Db::name($table)->where("pid", $pid)->where("type", $type)->where("jkstate", 1)->where("state", 1)->where("land_lx", 1)->where("ds_status", 0)->field($pk)->select();//查询数据
        $con = '';
        foreach($countcus as $v=>$val){
            $con.= $val[$pk].'|';
        }
        $array = explode("|",$con);// 拆分
        $data = [];
        foreach ($array as $v){
            if (!empty($v)){
                    $data[$v]=$v;//循环健值
            };
        }
        $num = "1";    //需要抽取的默认条数
        $a=array_rand($data,$num) ;//随机数组
        $account = Db::name("$table")->where($pk,$a)->find();
        $account = $this->rzjr($account);//账号限额配置
        $account = $this->ds($account);//账号限量配置
        return $account;
    }
    public function rzjr($data)//账号限额配置
    {
        if($data['r_money']!=0){//日限额开关
            if($data['r_money'] <= $data['jr_pay']){
                $this->success('1011',null,'暂无账户可用,请稍后再试');
            }
        }
        if($data['z_money']!=0){//总限额开关
            if($data['z_money'] <= $data['z_pay']){
                $this->success('1012',null,'暂无账户可用,请稍后再试');
            }
        }
        return $data;
    }
    public function ds($data)//账号限量配置
    {
        if($data['ds_time']!=0){//设定时间
            if($data['ds_type']==0){//限量模式
               $count = Db::name('pay_order')
               ->where("pid", $data["pid"])
               ->where("mid", $data['mid'])
               ->where("state", 2)
               ->whereTime('pay_date', '<=', time())
               ->whereTime('pay_date', '>=', time()-(60*$data['ds_time']))
               ->count();//已支付订单数量
            }else{
               $count = Db::name('pay_order')
               ->where("pid", $data["pid"])
               ->where("mid", $data['mid'])
               ->where("state", 1)
               ->whereTime('create_date', '<=', time())
               ->whereTime('create_date', '>=', time()-(60*$data['ds_time']))
               ->count();//新创建订单数量
            }
            if($data['ds_num'] <= $count){//限量数量
                Db::name("pay_gfg")->where("pid", $data['pid'])->where("id", $data['id'])->update(array("ds_status"=>1));
                $this->success('1010',null,'暂无账户可用,请稍后再试');
            }
        }
        return $data;
    }
    public function bug($data,$msg)//账号异常配置
    {
        if($msg=='该通道已关闭'){
            $count = Db::name('pay_gfg')->where("pid", $data["pid"])->where("id", $data['id'])->sum("bug_num");//异常次数
            Db::name("pay_gfg")->where("pid", $data['pid'])->where("id", $data['id'])->update(array("state"=>0,"land_lx"=>0,"bug_num"=>$count,"bug_data"=>$msg,"time"=>time()));
        }
        $res = Db::name("pay_user")->where("id",$data['pid'])->find();
        if($res['bug_num']<=$data['bug_num']){
            if($res['bug_type']==1){
                $count = Db::name('pay_gfg')->where("pid", $data["pid"])->where("id", $data['id'])->sum("bug_num");//异常次数
                Db::name("pay_gfg")->where("pid", $data['pid'])->where("id", $data['id'])->update(array("state"=>0,"land_lx"=>0,"bug_num"=>$count,"bug_data"=>$msg,"time"=>time()));
            }else{
                Db::table('pay_gfg')->where("pid", $data['pid'])->where("id", $data['id'])->delete();
                $land_count = Db::name('pay_gfg')->where("pid", $data["pid"])->where("typec_id", $data['typec_id'])->count();//账号数量
                $jr = Db::table('pay_order') ->where("pid", $data["pid"])->where("mid_id",$data['typec_id'])->where("state",2)->whereTime('create_date', 'today')->sum("money");//今日收入
                $zr = Db::table('pay_order') ->where("pid", $data["pid"])->where("mid_id",$data['typec_id'])->where("state",2)->whereTime('create_date', 'yesterday')->sum("money");//昨日收入
                Db::name("pay_jie")->where("pid", $data['pid'])->where("id", $data['typec_id'])->update(array("land_count"=>$land_count,"jr_pay"=>$jr,"zr_pay"=>$zr));
            }
        }else{
            $count = Db::name('pay_gfg')->where("pid", $data["pid"])->where("id", $data['id'])->sum("bug_num")+1;//异常次数
            Db::name("pay_gfg")->where("pid", $data['pid'])->where("id", $data['id'])->update(array("bug_num"=>$count));
        }
        return $data;
    }
    public function tongtao($data,$money,$type)//获取通道支付信息
    {
        $jie = Db::name("pay_jie")->where("pid", $data['pid'])->where("id", $data['typec_id'])->where("state", 1)->find();//获取通道
        if(!$jie){
            $this->bug($data,'该通道已关闭');//账号异常配置
            $this->success('1013',null,'订单创建失败（错误信息：该通道已关闭)');
        }
        $cls = app("\\app\common\controller\\".$jie['game_dm']);//支付通道路径
        $run = $cls->exec($data,$money,$type);//支付通道数据
        if($run['code']==-1){
            $this->bug($data,$run['data']);//账号异常配置
            $data = $this->land($data['pid'],$type);//随机账号
            $run = $this->tongtao($data,$money,$type);//获取通道支付信息
        }
        return $run;
    }
    public function mqf($pid,$data,$money,$type,$orderId)//获取金额判断
    {
        $jie = Db::name("pay_jie")->where("pid", $pid)->where("id", $data['typec_id'])->where("state", 1)->find();
        if($jie['game_dm']=='mq_gzfbjkd' || $jie['game_dm']=='mq_gvxjkd'){//监控端(微信)||监控端(支付宝)
            $reallyPrice = bcmul($money ,100);
            for ($i = 0; $i < 999; $i++) {
                $payQf = 1;
                $tmpPrice = $reallyPrice . "-" . $type. "-" . $jie['game_dm']. "-" . $data['pid'];
                $row = Db::execute("INSERT IGNORE INTO pay_tmp (pid,price,order_id) VALUES ('" . $pid . "','" . $tmpPrice . "','" . $orderId . "')");
                if ($row) {
                    $ok = true;
                    break;
                }
                if ($payQf == 1) {
                    $reallyPrice++;
                } else if ($payQf == 2) {
                    $reallyPrice--;
                }
            }
            $money = bcdiv($reallyPrice, 100,2);
            if (!$ok) {
                $this->success('1016',null,'订单创建失败（错误信息：订单创建超出负荷，请稍后重试)');
            }
        }else if($jie['game_dm']=='mq_gvxyjk'){//云监控(微信)
            $reallyPrice = bcmul($money ,100);
            for ($i = 0; $i < 9999; $i++) {
                $payQf = 1;
                $tmpPrice = $reallyPrice . "-" . $type. "-" . $jie['game_dm']. "-" . $data['pid'];
                $row = Db::execute("INSERT IGNORE INTO pay_tmp (pid,price,order_id) VALUES ('" . $pid . "','" . $tmpPrice . "','" . $orderId . "')");
                if ($row) {
                    $ok = true;
                    break;
                }
                if ($payQf == 1) {
                    $reallyPrice++;
                } else if ($payQf == 2) {
                    $reallyPrice--;
                }
            }
            $money = bcdiv($reallyPrice, 100,2);
            if (!$ok) {
                $this->success('1016',null,'订单创建失败（错误信息：订单创建超出负荷，请稍后重试)');
            }
        }else if($jie['game_dm']=='mq_gqqyjk'){//云监控(Q Q)
            $reallyPrice = bcmul($money ,100);
            for ($i = 0; $i < 999; $i++) {
                $payQf = 1;
                $tmpPrice = $reallyPrice . "-" . $type. "-" . $jie['game_dm']. "-" . $data['pid'];
                $row = Db::execute("INSERT IGNORE INTO pay_tmp (pid,price,order_id) VALUES ('" . $pid . "','" . $tmpPrice . "','" . $orderId . "')");
                if ($row) {
                    $ok = true;
                    break;
                }
                if ($payQf == 1) {
                    $reallyPrice++;
                } else if ($payQf == 2) {
                    $reallyPrice--;
                }
            }
            $money = bcdiv($reallyPrice, 100,2);
            if (!$ok) {
                $this->success('1016',null,'订单创建失败（错误信息：订单创建超出负荷，请稍后重试)');
            }
        }
        return $money;
    }
    public function pay2()//转跳自定义页面
    {
        $H5 = input('H5');//H5页面
        if($H5){
            $data = Db::name("pay_order")->where("order_id", $H5)->find();
            if(!$data){
                $this->success('1002',null,'order_id（附加信息：订单号错误（订单号）'); 
            }
            $data['order_url'] = $data['mid_url'];//H5链接
                // 模板变量赋值
            $this->assign('data',$data);
            return $this->fetch('pay/fxh5');
        }
    }
    public function pay()//转跳支付页面
    {
        $H5 = input('H5');//H5页面
        if($H5){
            $data = Db::name("pay_order")->where("order_id", $H5)->find();
            if(!$data){
                $this->success('1002',null,'order_id（附加信息：订单号错误（订单号）'); 
            }
            $url = $data['mid_url'];
            return redirect($url);
        }
        $Ali_PayH5 = input('Ali_PayH5');//支付宝H5页面
        if($Ali_PayH5){
            $data = Db::name("pay_order")->where("order_id", $Ali_PayH5)->find();
            if(!$data){
                $this->success('1002',null,'order_id（附加信息：订单号错误（订单号）'); 
            }
            $atad= Db::name("pay_gfg")->where("pid", $data['pid'])->where("mid", $data['mid'])->find();
            if($data['mid_dm']=='mq_gzfbyjk'){//云监控(支付宝)
                $data['mid_url'] = 'alipays://platformapi/startapp?appId=20000123&actionType=scan&biz_data='.urlencode('{"s": "money","u": "'.$atad['zhanghao'].'","a": "'.$data['money'].'","m":"'.$data['pay_id'].'"}');//H5转跳链接
            }
            if($data['mid_dm']=='mq_gzfbjkd'){//监控端(支付宝)
                $data['mid_url'] = $data['mid_url'];//H5转跳链接
            }
            $this->assign('data',$data);
            return $this->fetch('pay/Ali_PayH5');
        }
        $orderid = input('orderid');;
        if (!$orderid || $orderid == "") {
            $this->success('1001',null,'order_id（附加信息：请输入订单号（云端订单号）参数错误');
        }
        $data = Db::name("pay_order")->where("order_id", $orderid)->find();
        if(!$data){
               $this->success('1002',null,'order_id（附加信息：订单号错误（订单号）'); 
        }
        $atad= Db::name("pay_gfg")->where("pid", $data['pid'])->where("mid", $data['mid'])->find();
        $ree = Db::name("pay_jie")->where("pid", $data['pid'])->where("id",$data['mid_id'])->find();
        $cls = app("\\app\common\controller\\".$ree['game_dm']);//支付通道路径
        $run = $cls->fukyem($data);//支付通道数据
        return $run;
    }
    public function enQrcode($url)//生成二维码
    {
        $data = Db::name("pay_sz")->find();
        // 自定义二维码配置
        $config = [
            'title'         => true,
            'title_content' => $data['web_name'],
            'logo'          => false,
            'logo_url'      => (input('logo')==''? './static/user/assets/images/favicon.ico':input('logo')),
            'logo_size'     => 50,
        ];
        $qr_code = new QrcodeServer($config);
        $content = $qr_code->createServer($url);
        return response($content,250,['Content-Length'=>strlen($content)])->contentType('image/png');
    }
}